package com.dlc.shop.distribution.multishop.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dlc.shop.bean.enums.OfflineHandleEventType;
import com.dlc.shop.bean.enums.ShopStatus;
import com.dlc.shop.bean.model.OfflineHandleEvent;
import com.dlc.shop.bean.model.Product;
import com.dlc.shop.bean.model.ShopDetail;
import com.dlc.shop.bean.model.Sku;
import com.dlc.shop.bean.param.OfflineHandleEventAuditParam;
import com.dlc.shop.bean.param.ProductParam;
import com.dlc.shop.common.enums.StatusEnum;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.i18n.I18nMessage;
import com.dlc.shop.common.response.ResponseEnum;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.common.util.Arith;
import com.dlc.shop.common.util.PageParam;
import com.dlc.shop.distribution.common.constants.DistributionProdStateEnum;
import com.dlc.shop.distribution.common.model.DistributionProd;
import com.dlc.shop.distribution.common.model.DistributionProdLog;
import com.dlc.shop.distribution.common.service.DistributionProdService;
import com.dlc.shop.security.multishop.util.SecurityUtils;
import com.dlc.shop.service.OfflineHandleEventService;
import com.dlc.shop.service.ProductService;
import com.dlc.shop.service.ShopDetailService;
import com.dlc.shop.service.SkuService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author lgh on 2019/04/01.
 */
@RestController
@RequestMapping("/distribution/distributionProd")
@AllArgsConstructor
@Tag(name = "商家端分销商品接口")
public class DistributionProdController {

    private final DistributionProdService distributionProdService;

    private final OfflineHandleEventService offlineHandleEventService;

    private final ProductService productService;

    private final SkuService skuService;

    private final ShopDetailService shopDetailService;

    @GetMapping("/count")
    @Operation(summary = "根据商品id计算分销商品数量" , description = "根据商品id获取")
    @Parameter(name = "prodId", description = "商品id" , required = true)
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:count')")
    public ServerResponseEntity<Long> count(Long prodId) {
        return ServerResponseEntity.success(distributionProdService.count(new LambdaQueryWrapper<DistributionProd>()
                .eq(DistributionProd::getProdId, prodId)));
    }

    @GetMapping("/canDistributionProdPage")
    @Operation(summary = "分页查找可以添加到分销商品的数据")
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:page')")
    public ServerResponseEntity<IPage<Product>> canDistributionProdPage(ProductParam product, PageParam<Product> page) {
        product.setShopId(SecurityUtils.getShopUser().getShopId());
        product.setLang(I18nMessage.getLang());
        IPage<Product> products = productService.canDistributionProdPage(page, product);
        return ServerResponseEntity.success(products);
    }

    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:page')")
    @Operation(summary = "分页查找分销商品数据")
    @Parameters({
            @Parameter(name = "prodName", description = "商品名称" , required = true),
            @Parameter(name = "state", description = "分销商品状态(0:商家下架 1:商家上架 2:违规下架 3:平台审核)" , required = true)
    })
    public ServerResponseEntity<IPage<DistributionProd>> page(DistributionProd distributionProd, PageParam<DistributionProd> page,
                                                        String prodName, Integer state) {
        distributionProd.setShopId(SecurityUtils.getShopUser().getShopId());
        distributionProd.setState(state);
        IPage<DistributionProd> list = distributionProdService.distributionProdsPage(page, distributionProd, prodName);
        return ServerResponseEntity.success(list);
    }

    @GetMapping("/info/{id}")
    @Operation(summary = "根据分销商品id查看分销商品数据" , description = "根据分销商品id获取")
    @Parameter(name = "id", description = "分销商品id" , required = true)
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:info')")
    public ServerResponseEntity<DistributionProd> info(@PathVariable("id") Long id) {
        DistributionProd distributionProd = distributionProdService.getById(id);
        return ServerResponseEntity.success(distributionProd);
    }

    @PostMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:save')")
    @Operation(summary = "保存分销商品")
    public ServerResponseEntity<Void> save(@RequestBody @Valid DistributionProd distributionProd) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        distributionProd.setShopId(shopId);
        // 防止重复提交
        long count = distributionProdService.count(new LambdaQueryWrapper<DistributionProd>()
                .eq(DistributionProd::getProdId, distributionProd.getProdId())
                .eq(DistributionProd::getShopId, distributionProd.getShopId()));
        if (count > 0) {
            // 分销商品已经存在
            throw new YamiShopBindException("yami.distribution.prod.exist");
        }
        // 校验数据
        validateDistributionProd(distributionProd, shopId, true);
        setDefaultAwardNumbers(distributionProd);
        distributionProdService.save(distributionProd);
        distributionProdService.removeDistributionProdPoCacheByProdId(distributionProd.getProdId());
        return ServerResponseEntity.success();
    }

    @PutMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:update')")
    @Operation(summary = "修改分销商品")
    public ServerResponseEntity<Void> update(@RequestBody @Valid DistributionProd distributionProd) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        // 校验数据
        validateDistributionProd(distributionProd, shopId, false);

        setDefaultAwardNumbers(distributionProd);
        distributionProdService.updateById(distributionProd);
        distributionProdService.removeDistributionProdPoCacheByProdId(distributionProd.getProdId());
        return ServerResponseEntity.success();
    }

    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:delete')")
    @Operation(summary = "根据分销商品id列表批量删除分销商品")
    @Parameter(name = "ids", description = "分销商品ids" , required = true)
    public ServerResponseEntity<Void> delete(@RequestBody List<Long> ids) {
        distributionProdService.removeByIds(ids);
        return ServerResponseEntity.success();
    }

    private void setDefaultAwardNumbers(@Valid @RequestBody DistributionProd distributionProd) {
        if (StrUtil.isBlank(distributionProd.getParentAwardNumbers())) {
            // 固定奖励
            if (Objects.equals(distributionProd.getAwardNumberSet(), 0)) {
                distributionProd.setParentAwardNumbers("0");
            } else {
                distributionProd.setParentAwardNumbers(null);
            }
        }
        if(Objects.equals(distributionProd.getParentAwardSet(),0)){
            distributionProd.setParentAwardNumbers("0");
        }
        if (StrUtil.isBlank(distributionProd.getAwardNumbers())) {
            distributionProd.setAwardNumbers("0");
            // 固定奖励
            if (Objects.equals(distributionProd.getAwardNumberSet(), 0)) {
                distributionProd.setAwardNumbers("0");
            } else {
                distributionProd.setAwardNumbers(null);
            }
        }
        distributionProd.setUpdateTime(new Date());
    }

    @GetMapping("/getOfflineEventByDistProdId/{distributionProdId}")
    @Operation(summary = "根据分销商品id获取下线信息")
    @Parameter(name = "distributionProdId", description = "分销商品id" , required = true)
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:offlineInfo')")
    public ServerResponseEntity<OfflineHandleEvent> getOfflineEventByDistProdId(@PathVariable("distributionProdId") Long distributionProdId) {
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.DISTRIBUTION_PROD.getValue(), distributionProdId);
        return ServerResponseEntity.success(offlineHandleEvent);
    }

    @PostMapping("/auditApply")
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:auditApply')")
    @Operation(summary = "违规商品提交审核")
    public ServerResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        DistributionProd distributionProd = distributionProdService.getById(offlineHandleEventAuditParam.getHandleId());
        if (distributionProd == null) {
            // 未找到分销商品信息信息
            throw new YamiShopBindException("yami.distribution.prod.exist.error");
        }
        distributionProdService.auditApply(offlineHandleEventAuditParam.getEventId(), offlineHandleEventAuditParam.getHandleId(), offlineHandleEventAuditParam.getReapplyReason());
        return ServerResponseEntity.success();
    }

    @GetMapping("/getDistributionProdLogPage")
    @Operation(summary = "获取分销商品销售记录信息")
    @PreAuthorize("@pms.hasPermission('distribution:distributionProd:pageLog')")
    public ServerResponseEntity<IPage<DistributionProdLog>> getDistributionProdLogPage(DistributionProdLog distributionProdLog,
                                                                                 PageParam<DistributionProdLog> page) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        distributionProdLog.setShopId(shopId);
        IPage<DistributionProdLog> distributionProdLogL = distributionProdService.getDistributionProdLogPage(page, distributionProdLog);
        return ServerResponseEntity.success(distributionProdLogL);
    }

    /**
     * 校验数据
     */
    private void validateDistributionProd(DistributionProd distributionProd, Long shopId, Boolean createOrUpdate) {
        List<Sku> skus = skuService.listSkuByProdId(distributionProd.getProdId());
        if (CollUtil.isEmpty(skus)) {
            // 未找到此商品
            throw new YamiShopBindException("yami.product.not.exist");
        }
        double maxPrice = 0;
        for (Sku sku : skus) {
            if (sku.getPrice() > maxPrice) {
                maxPrice = sku.getPrice();
            }
        }
        Product product = productService.getProductByProdId(distributionProd.getProdId());
        if (CollUtil.isEmpty(skus) || Objects.isNull(product)) {
            // 未找到此商品
            throw new YamiShopBindException("yami.product.not.exist");
        }
        // 检查店铺信息
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        if (Objects.isNull(shopDetail)) {
            throw new YamiShopBindException("找不到店铺信息");
        }
        if (!Objects.equals(shopDetail.getShopStatus(), ShopStatus.STOP.value()) && !Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value())) {
            // 店铺处于违规下架状态时
            if (createOrUpdate) {
                // 不能新增分销商品
                throw new YamiShopBindException("店铺处于违规下架状态，不能新增分销商品");
            } else {
                if (Objects.equals(distributionProd.getState(), DistributionProdStateEnum.PUT_ON.getValue())) {
                    // 不能把分销商品更新为上架状态
                    throw new YamiShopBindException("店铺处于违规下架状态，不能将分销商品置为上架状态");
                }
            }
        }
        if (!createOrUpdate) {
            if (Objects.equals(distributionProd.getState(), 1) && !Objects.equals(product.getStatus(), StatusEnum.ENABLE.value())) {
                // 商品不处于上线状态，分销商品不能进行上架操作
                throw new YamiShopBindException("yami.product.off.not.enable.disProduct");
            }
            DistributionProd dbDistributionProd = distributionProdService.getById(distributionProd.getDistributionProdId());
            if (Objects.isNull(dbDistributionProd)) {
                // 分销商品已经被删除
                throw new YamiShopBindException("当前分销商品已经被删除");
            }
            if (!Objects.equals(shopId, dbDistributionProd.getShopId())) {
                //没有权限
                throw new YamiShopBindException(ResponseEnum.UNAUTHORIZED);
            }
            if (Objects.equals(dbDistributionProd.getState(), DistributionProdStateEnum.OFFLINE.getValue()) || Objects.equals(dbDistributionProd.getState(), DistributionProdStateEnum.WAIT_AUDIT.getValue())) {
                // 分销商品处于违规下架状态，商家不能直接修改状态
                distributionProd.setState(dbDistributionProd.getState());
            }
        } else {
            // 如果商品不是上架状态，则把分销商品置为下架状态
            distributionProd.setState(Objects.equals(product.getStatus(), StatusEnum.ENABLE.value()) ? distributionProd.getState() : 0);
        }
        // 如果不使用需要校验
        if (distributionProd.getDefaultReward() == 1) {
            return;
        }
        int hundred = 100;
        directPushReward(distributionProd, maxPrice, hundred);
        // 查看是否有开启邀请人奖励
        if (distributionProd.getParentAwardSet() == 0) {
            return;
        }
        interPushBonus(distributionProd, maxPrice, hundred);
    }

    private void interPushBonus(DistributionProd distributionProd, double maxPrice, int hundred) {
        double parentAwardNum = Double.parseDouble(distributionProd.getParentAwardNumbers());
        double awardNum = Double.parseDouble(distributionProd.getAwardNumbers());
        // 按比例
        if (distributionProd.getAwardProportion() == 0) {
            // 奖励数额设置(0 固定奖励,1 根据等级奖励)
            if (distributionProd.getAwardNumberSet() == 0) {

                if (Double.parseDouble(distributionProd.getParentAwardNumbers()) >= hundred) {
                    // 邀请人固定奖励比例设置不能超过100%
                    throw new YamiShopBindException("yami.distribution.prod.parent.award");
                }
                if (Arith.add(parentAwardNum, awardNum) >= hundred) {
                    // 奖励设置不能大于等于商品最高价或者100%
                    throw new YamiShopBindException("yami.distribution.prod.price.check");
                }
            }
            if (distributionProd.getAwardNumberSet() == 1) {
                List<String> awardList = JSONUtil.parseArray(distributionProd.getParentAwardNumbers()).toList(String.class);
                List<Double> list = awardList.stream().map(Double::parseDouble).toList();
                if (list.stream().anyMatch(item -> item > hundred)) {
                    // 邀请人等级奖励比例设置不能超过100%
                    throw new YamiShopBindException("yami.distribution.prod.parent.level");
                }
            }

        }
        // 按金额
        if (distributionProd.getAwardProportion() == 1) {
            // 奖励数额设置(0 固定奖励,1 根据等级奖励)
            if (distributionProd.getAwardNumberSet() == 0) {
                if (Double.parseDouble(distributionProd.getParentAwardNumbers()) > maxPrice) {
                    // 邀请人固定奖励不能大于或等于商品的最高价
                    throw new YamiShopBindException("yami.distribution.prod.parentAward.check");
                }
                if (Arith.add(parentAwardNum, awardNum) >= maxPrice) {
                    // 奖励设置不能大于等于商品最高价或者100%
                    throw new YamiShopBindException("yami.distribution.prod.price.check");
                }
            }
            if (distributionProd.getAwardNumberSet() == 1) {
                List<String> awardList = JSONUtil.parseArray(distributionProd.getParentAwardNumbers()).toList(String.class);
                List<Double> list = awardList.stream().map(Double::parseDouble).toList();
                if (list.stream().anyMatch(item -> item > maxPrice)) {
                    // 邀请人等级奖励不能大于或等于商品的最高价
                    throw new YamiShopBindException("yami.distribution.prod.parentLevel.check");
                }
            }
        }
    }

    private void directPushReward(DistributionProd distributionProd, double maxPrice, int hundred) {
        // 按比例
        if (distributionProd.getAwardProportion() == 0) {
            // 奖励数额设置(0 固定奖励,1 根据等级奖励)
            if (distributionProd.getAwardNumberSet() == 0) {
                if (Double.parseDouble(distributionProd.getAwardNumbers()) >= hundred) {
                    // 固定奖励比例设置不能超过100%
                    throw new YamiShopBindException("yami.distribution.prod.award");
                }
            }
            if (distributionProd.getAwardNumberSet() == 1) {
                List<String> awardList = JSONUtil.parseArray(distributionProd.getAwardNumbers()).toList(String.class);
                List<Double> list = awardList.stream().map(Double::parseDouble).toList();
                if (list.stream().anyMatch(item -> item > hundred)) {
                    // 等级奖励比例设置不能超过100%
                    throw new YamiShopBindException("yami.distribution.prod.level");
                }
            }
        }
        // 按金额
        if (distributionProd.getAwardProportion() == 1) {
            // 奖励数额设置(0 固定奖励,1 根据等级奖励)
            if (distributionProd.getAwardNumberSet() == 0) {
                if (Double.parseDouble(distributionProd.getAwardNumbers()) >= maxPrice) {
                    // 固定奖励设置不能大于等于商品的最高价
                    throw new YamiShopBindException("yami.distribution.prod.award.check");
                }
            }
            if (distributionProd.getAwardNumberSet() == 1) {
                List<String> awardList = JSONUtil.parseArray(distributionProd.getAwardNumbers()).toList(String.class);
                List<Double> list = awardList.stream().map(Double::parseDouble).toList();
                if (list.stream().anyMatch(item -> item > maxPrice)) {
                    // 等级奖励设置不能超过商品的最低价
                    throw new YamiShopBindException("yami.distribution.prod.level.check");
                }
            }
        }
    }
}
